package com.engine4cloud.tdf.supervision.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.supervision.convert.JzdxAccompliceCrimeNameConvert;
import com.engine4cloud.tdf.supervision.dto.AccompliceCrimeNameDTO;
import com.engine4cloud.tdf.supervision.dto.query.JzdxAccompliceCrimeNameQueryDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxAccompliceCrimeNameResultDTO;
import com.engine4cloud.tdf.supervision.entity.JzdxAccompliceCrimeNameEntity;
import com.engine4cloud.tdf.supervision.entity.JzdxAccompliceEntity;
import com.engine4cloud.tdf.supervision.mapper.JzdxAccompliceCrimeNameMapper;
import com.engine4cloud.tdf.supervision.service.JzdxAccompliceCrimeNameService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 矫正对象同案犯具体罪名表
 *
 * @author wenjie
 * @date 2024-04-01 14:25:23
 */
@Service
public class JzdxAccompliceCrimeNameServiceImpl extends ServiceImpl<JzdxAccompliceCrimeNameMapper, JzdxAccompliceCrimeNameEntity> implements JzdxAccompliceCrimeNameService {
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateBatch(JzdxAccompliceEntity accomplice, List<AccompliceCrimeNameDTO> crimeNameList) {
        JzdxAccompliceCrimeNameQueryDTO query = new JzdxAccompliceCrimeNameQueryDTO(accomplice.getTafbh());
        List<JzdxAccompliceCrimeNameResultDTO> existedList = this.findList(query);

        List<JzdxAccompliceCrimeNameEntity> preSavedCrimeNameList = this.preSaveCrimeNameList(accomplice, existedList, crimeNameList);
        if (CollectionUtils.isNotEmpty(preSavedCrimeNameList)) {
            this.saveBatch(preSavedCrimeNameList);
        }

        List<Long> preDeletedCrimeNameList = this.preDeleteCrimeNameIdList(existedList, crimeNameList);
        if (CollectionUtils.isNotEmpty(preDeletedCrimeNameList)) {
            this.removeBatchByIds(preDeletedCrimeNameList);
        }

        return true;
    }

    private List<JzdxAccompliceCrimeNameEntity> preSaveCrimeNameList(JzdxAccompliceEntity accomplice, List<JzdxAccompliceCrimeNameResultDTO> existedList, List<AccompliceCrimeNameDTO> crimeNameList) {
        if (CollectionUtils.isEmpty(crimeNameList)) {
            return Collections.emptyList();
        }

        List<JzdxAccompliceCrimeNameEntity> preSaveCrimeNameList = new ArrayList<>();
        Map<String, JzdxAccompliceCrimeNameResultDTO> existedMap = existedList.stream().collect(Collectors.toMap(JzdxAccompliceCrimeNameResultDTO::getJtzm, Function.identity(), (v1, v2) -> v1));
        crimeNameList.forEach(crime -> {
            if (!existedMap.containsKey(crime.getJtzm())) {
                preSaveCrimeNameList.add(JzdxAccompliceCrimeNameConvert.INSTANCE.update(accomplice, crime.getJtzm()));
            }
        });

        return preSaveCrimeNameList;
    }

    private List<Long> preDeleteCrimeNameIdList(List<JzdxAccompliceCrimeNameResultDTO> existedList, List<AccompliceCrimeNameDTO> crimeNameList) {
        if (CollectionUtils.isEmpty(existedList)) {
            return Collections.emptyList();
        }

        Map<String, AccompliceCrimeNameDTO> crimeMap = crimeNameList.stream().collect(Collectors.toMap(AccompliceCrimeNameDTO::getJtzm, Function.identity(), (v1, v2) -> v1));
        return existedList.stream().filter(e -> !crimeMap.containsKey(e.getJtzm())).map(JzdxAccompliceCrimeNameResultDTO::getId).toList();
    }

    @Override
    public List<JzdxAccompliceCrimeNameResultDTO> findList(JzdxAccompliceCrimeNameQueryDTO query) {
        return this.baseMapper.pageList(query);
    }
}